<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2020/4/22
 * Time: 10:09
 */

namespace app\adminapiv3\service;


class DataBak extends Base
{
    /**
     * @name: 备份列表
     * @Param:
     * @Description:
     * @Author: foo
     * @Date: 2019-04-24 15:46:03
     */
    public function list ($params, $limit)
    {
        $service = new ServerData();
        $list = $service->list($params, $limit);

        foreach ($list['data'] as $k => $v){
            $list['data'][$k]['ctime'] = date('Y-m-d H:i:s',$v['ctime']);
        }

        return $list;
    }

    /**
     * @name 备份数据库
     * @Author wx
     * @date 2019/8/9 14:39
     */
    function backup($backup)
    {
        /*创建数据库的语句
        $nowDataBase = 'database()';
        $dtabase = Db::query('select ' . $nowDataBase );
        $data = Db::query('show create database ' . $dtabase[0][$nowDataBase]);
        $database_s = $data[0]['Create Database'] .";\n";
        $database_s = 'DROP DATABASE IF EXISTS `'.$data[0]['Database']."`;\n".$database_s;*/

        if($backup != 1){
            $this->setError($this->FAIL_CODE, '参数错误!');
            return false;
        }

        //1. 生成sql文件
        $dbConfig = config('database.');

        $db_user = $dbConfig['username'];//数据库账号
        $db_pwd = $dbConfig['password'];//数据库密码
        $db_port = $dbConfig['hostport'];//端口
        $db_database = $dbConfig['database'];//数据库名

        $fileName = date("Y-m-d")."-".time();
        $bakDir = dirname($_SERVER['DOCUMENT_ROOT']).'/runtime/MysqlBak';//备份目录

        if (!file_exists($bakDir)) {
            mkdir($bakDir,0777,true);
        }
        $bakName = $bakDir.'/'.$fileName.'.sql';

        if(FALSE ===  stristr(php_uname('s'),"win"))
        {
            //linux备份
            $backupLinuxSql = "jzzdbback -u$db_user -p$db_pwd  -P$db_port $db_database >> $bakName";

            exec($backupLinuxSql);
        }
        else
        {
            //windows备份
            $backupWindowsSql = "#InstallPath#JZZDBBACK -u$db_user -p$db_pwd -P$db_port --default-character-set=utf8 $db_database >> $bakName";

            exec($backupWindowsSql);
        }

        //2. 插入数据库
        $service = new DatabaseBackup();
        $service->add($bakName,1);

    }

    /**
     * @name 清空数据库
     * 清空的数据表
    统计表 jzz_statistics
    网络攻击详情表 jzz_network_attack
    文件攻击详情表 jzz_file_attack
    文件篡改详情表 jzz_file_illegal_modify
    云安全日志 jzz_cloud_safe
    更新日志 jzz_server_update
    文件查杀 jzz_host_file_screening
    管理员登陆日志 jzz_user_login_log
    系统提权 jzz_file_empowerment
     * @param $params
     * @return bool
     * @Author wx
     * @date 2019/8/13 14:19
     */
    function clear($params)
    {

        if($params != 1){
            $this->setError($this->FAIL_CODE, '参数错误');
            return false;
        }

        $databaseConf = config('database.');
        $prefix = $databaseConf['prefix'];

        //清空的数据表操作
        $tables = array(
            'statistics',
            'network_attack',
            'file_attack',
            'file_illegal_modify',
            'cloud_safe',
            'server_update',
            'host_file_screening',
            'file_empowerment'
        );
        foreach ($tables as $k => $v){
            db()->query("TRUNCATE TABLE ".$prefix.$v);
        }

        return true;
    }





    /**
     * @name 还原数据库
     * @param $id
     * @Author wx
     * @date 2019/4/25 13:05
     */

    function reset($id) {

        if(!$id){
            $this->setError($this->FAIL_CODE, '参数错误');
            return false;
        }

        if(!$id){
            $this->setError($this->FAIL_CODE, '参数错误');
            return false;
        }

        $service = new DatabaseBackup();
        $info = $service->findData($id);

        if(!$info || !file_exists($info['path'])){
            $this->setError($this->FAIL_CODE, '没有该数据');
        }

        $dbConfig = config('database.');

        $db_user = $dbConfig['username'];//数据库账号
        $db_pwd = $dbConfig['password'];//数据库密码
        $db_port = $dbConfig['hostport'];//端口
        $db_database = $dbConfig['database'];//数据库名

        if(FALSE ===  stristr(php_uname('s'),"win"))
        {
            //linux还原
            $resetSql = 'jzzdb -u'.$db_user.' -p'.$db_pwd .'   '. $db_database.'  -e  "source '.$info['path'].';" ';
        }
        else
        {
            //windows还原 exec("#InstallPath#jzzdb $DB_DB < $tmpFile", $output, $return_val);
            $resetSql = '#InstallPath# jzzdb -u'.$db_user.' -p'.$db_pwd .'   '. $db_database.'  -e  "source '.$info['path'].';" ';
        }

        exec($resetSql);
    }

    function resetSql($path)
    {
        // sql文件包含的sql语句数组
        $sqls = array ();
        $f = fopen ( $path, "rb" );
        // 创建表缓冲变量
        $create = '';
        while ( !feof ( $f ) ) {
            // 读取每一行sql
            $line = fgets ( $f );
            if (trim ( $line ) == '') {
                continue;
            }
            // 如果结尾包含';'(即为一个完整的sql语句，这里是插入语句)，并且不包含'ENGINE='(即创建表的最后一句)，
            if (! preg_match ( '/;/', $line, $match ) || preg_match ( '/ENGINE=/', $line, $match )) {
                // 将本次sql语句与创建表sql连接存起来
                $create .= $line;
                // 如果包含了创建表的最后一句
                if (preg_match ( '/ENGINE=/', $create, $match )) {
                    // 则将其合并到sql数组
                    $sqls [] = $create;
                    // 清空当前，准备下一个表的创建
                    $create = '';
                }
                // 跳过本次
                continue;
            }
            $sqls [] = $line;
        }
        fclose ($f);

        foreach ($sqls as $k => $v)
        {
            str_replace ( "\n", "", $v );
            Db::query (  $v  );
        }

        return true;
    }



    /**
     * @name: 清空备份目录
     * @Param:
     * @Description:
     * @Author: wx
     * @Date: 2019-04-24 15:45:12
     */
    function clearDir ($params)
    {
        if($params != 1){
            $this->setError($this->FAIL_CODE, '参数错误');
            return false;
        }


        $service = new DatabaseBackup();
        $service->clearDir();

        //删除目录下的文件
        $path = '../runtime/MysqlBak/';
        $this->delFile($path);

        return true;
    }

    /**
     * @name 删除指定目录下的所有文件
     * @param $path
     * @Author wx
     * @date 2019/4/26 10:04
     */
    function delFile($path){
        //如果是目录则继续
        if(is_dir($path)) {
            //扫描一个文件夹内的所有文件夹和文件并返回数组
            $p = scandir($path);
            foreach ($p as $val) {
                //排除目录中的.和..
                if ($val != "." && $val != "..") {
                    //如果是文件直接删除
                    unlink($path . $val);
                }
            }
        }
    }


    /**
     * @name 返回一张表的sql语句
     * @param $table
     * @return string
     * @Author wx
     * @date 2019/4/25 13:54
     */
    function dump_table($table) {
        $tables = Db::query("show create table $table");

        $mysql = "DROP TABLE IF EXISTS " . $table . ";\n";

        $mysql .= $tables[0]['Create Table'] . ";\n";

        $data = Db::query("select * from " . $table);
        foreach($data as $v) {
            $key = $this->processKeys($v);

            $value = $this->processValues($v);

            $mysql .= "insert into `$table`($key) values($value);\n";
        }
        $mysql .= "\n";

        return $mysql;
    }

    function processKeys ($data)
    {
        $keys = array_keys($data);
        $keys = array_map('addslashes', $keys);
        $keys = join('`,`', $keys);
        $keys = "`" . $keys . "`";

        return $keys;
    }

    function processValues ($data)
    {
        $values = array_values($data);
        $values = array_map('addslashes', $values);
        $values = join("','", $values);
        $values = "'" . $values . "'";

        return $values;
    }
}